package icasue.runninginvoke.config.properties;

import lombok.Data;
import org.apache.logging.log4j.util.Strings;
import org.springframework.boot.context.properties.ConfigurationProperties;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.BlockingDeque;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.TimeUnit;

/**
 * @Author: Qiao Hang
 * @CreateDate: 2021/11/27 上午8:27
 * @UpdateDate:
 * @Description:
 */
@Data
@ConfigurationProperties(prefix = "task")
public class TasksConfigProperties {

    public Boolean enable = false;

    public Boolean security = true;

    /*
        应用程序暴露在WEB端的端口是否被容器技术映射过，
        常见于于应用使用容器技术负载部署的情况，例如docker端口映射.
    */
    public Boolean webPortHadBeenMapping = false;

    public String redisKeyHome = "runninginvoke:task:key";

    public Reference reference = new Reference();

    public InnerTheadPool theadPool = new InnerTheadPool();

    public List<TaskDeclare> taskDeclares = new ArrayList<>();

    public List<String> taskResourcePaths = new ArrayList<>();

    @Data
    public static class Reference{
        // Jedis连接池引用
        public String jedisPool;
        // redis连接工厂引用
        public String redisConnectionFactory;
        // 线程池引用(优先级: 引用 > 配置 > 默认)
        public String threadPool;
    }

    @Data
    public static class InnerTheadPool{
        public Integer coreSize = 5;
        public Integer maxSize = Integer.MAX_VALUE;
        public Long keepAliveTime = 0L;
        // 存活时间单位(默认毫秒)
        public TimeUnit timeUnit = TimeUnit.MILLISECONDS;
        // 工作队列类型.
        public Class<? extends BlockingDeque> workQueue = LinkedBlockingDeque.class;
    }

    @Data
    public static class TaskDeclare {
        // 任务ID
        public String taskId;
        // 调度策略(针对独立部署与负载模式，分为 'all', 'single')
        public TaskStrategy strategy = TaskStrategy.ALL;
        // 当任务为周期性任务时，任务执行的 corn 表达式.
        public String corn;
        // 方法句柄描述.
        public String functionDescription = Strings.EMPTY;
        // 可反射的类名.
        public String className;
        // 可反射的方法名.
        public String methodName;
        // 参数表列.
        public List<Param> params = new ArrayList();

        @Data
        public static class Param{
            // 参数描述.
            public String paramDoc = Strings.EMPTY;
            // 可反射的参数类.
            public String paramClassName;
            // 参数值.
            public Object paramValue;
        }

        public enum TaskStrategy{
            ALL,
            SINGLE
        }
    }

}
